package com.gph.saviorframework.os.authz.token;

import com.gph.saviorframework.os.authz.OAuthTokenxRequest;
import com.gph.saviorframework.os.authz.validator.AbstractClientDetailsValidator;
import com.gph.saviorframework.os.authz.validator.AuthorizationCodeClientDetailsValidator;
import com.gph.saviorframework.os.authz.web.WebUtils;
import com.gph.saviorframework.os.model.oauth.AccessToken;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AuthorizationCodeTokenHandler extends AbstractOAuthTokenHandler {

    private static final Logger log = LoggerFactory.getLogger(AuthorizationCodeTokenHandler.class);

    public boolean support(OAuthTokenxRequest tokenRequest) throws OAuthProblemException {
        final String grantType = tokenRequest.getGrantType();
        return GrantType.AUTHORIZATION_CODE.toString().equalsIgnoreCase(grantType);
    }

    /*
    *
    * /oauth/token?client_id=unity-client&client_secret=unity&grant_type=authorization_code&code=zLl170&redirect_uri=redirect_uri
    * */
    public void handleAfterValidation() throws OAuthProblemException, OAuthSystemException {
        //response token, always new
        responseToken();

        //remove code lastly
        removeCode();
    }

    private void removeCode() {
        final String code = tokenRequest.getCode();
        final boolean result = oauthService.removeOauthCode(code, clientDetails());
        log.debug("Remove code: {} result: {}", code, result);
    }

    private void responseToken() throws OAuthSystemException {
        AccessToken accessToken = oauthService.retrieveAuthorizationCodeAccessToken(clientDetails(), tokenRequest.getCode());
        final OAuthResponse tokenResponse = createTokenResponse(accessToken, false);

        log.debug("'authorization_code' response: {}", tokenResponse);
        WebUtils.writeOAuthJsonResponse(response, tokenResponse);
    }

    protected AbstractClientDetailsValidator getValidator() {
        return new AuthorizationCodeClientDetailsValidator(tokenRequest);
    }
}
